//
//  MethodPatcher
//
//  Created by Caue W. on 2011-03-08.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//
package time.types.ds.reflection;
import time.types.ds.ObjectHash;

/**
* This class should give the optimal way to add a static storage facility to a class that can
*  be accessed by its instances (and instances of its subclasses). On prototype-based vms, this
*  is achieved by setting their prototype.
*  Otherwise, this is achieved by a static ObjectHash
**/
class ClassBasedStorage 
{
#if !(flash || flash9 || js || neko)
	static var hash:ObjectHash< Class<Dynamic>, Hash<Dynamic> > = new ObjectHash();
#end

	public function new()
	{
	}
	
	public function set<T>(cl:Class<T>, name:String, val:Dynamic) : Void
	{
#if !(flash || flash9 || js || neko)
		var h = hash.get(cl);
		if (h == null)
		{
			h = new Hash();
			hash.set(cl, h);
		}
		
		h.set(name, val);
#else
		var proto = untyped cl.prototype;
		Reflect.setField(proto, "$" + name, val);
#end
	}
	
	public function get<T>(inst:T, name:String) : Dynamic
	{
#if !(flash || flash9 || js || neko)
		var cl:Class<Dynamic> = Type.getClass(inst);
		var m = null;
		
		while(m == null && cl != null)
		{
			var h = hash.get(cl);
			m = (h == null) ? null : h.get(name);
			
			cl = Type.getsuperClass(cl);
		}
		
		return m;
#else
		return Reflect.field(inst, "$" + name);
#end
	}
	
}